import { UserFocusPhotos, UserFocusPhotosDocument } from '@api/user/schemas/userFocusPhotos.schema';
import { ReqUser } from '@common/auth';
import { FileUpload, UploadStrategy } from '@domain/uploadStrategy';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model, ObjectId, Types } from 'mongoose';
import { CreatePhotoDto } from './dto/create-photo.dto';
import { ListPhotoDto } from './dto/list-photos.dto';
import { UpdatePhotoDto } from './dto/update-photo.dto';
import { Photos, PhotosDocument } from './schemas/photos.schema';
import { PhotosProfileService } from './photosProfile.service';

@Injectable()
export class PhotosService {
    constructor(
        @InjectModel(Photos.name) private photosModel: Model<PhotosDocument>,
        @InjectModel(UserFocusPhotos.name) private userFocusPhotosModel: Model<UserFocusPhotosDocument>,
        private photosProfileService: PhotosProfileService
    ) {}

    async create(createPhotoDto: CreatePhotoDto, reqUser: ReqUser, files: Express.Multer.File[]) {
        const entity = new this.photosModel(createPhotoDto);
        const fileUpload = new FileUpload(UploadStrategy.USER_PHOTOS_UPLOAD);
        const fileUrl = await fileUpload.upload(reqUser, files, entity._id);
        entity.user = reqUser._id;
        entity.photosType = createPhotoDto.typeId;
        entity.photos = fileUrl;

        const profile = await this.photosProfileService.findOneOrCreate(entity._id);
        entity.profile = profile._id;
        return await entity.save();
    }
    async list(dto: ListPhotoDto) {
        const { page = 0, psize = 20 } = dto.limit || {};
        dto.where.auditStatus = dto.where.auditStatus ?? 1;
        const keyword = dto.where.keyword;
        Reflect.deleteProperty(dto.where, 'keyword');
        const res = await this.photosModel
            .find(dto.where)
            .where(
                keyword
                    ? {
                          $or: [{ title: { $regex: keyword } }, { desc: { $regex: keyword } }],
                      }
                    : {}
            )
            .populate([
                { path: 'user', select: 'nickname avatar desc' },
                { path: 'profile', select: 'totalDown' },
            ])
            .skip(page * psize)
            .limit(psize)
            // .sort('-profile.totalDown')
            .sort('-createdAt')
            .exec();
        return res;
    }

    findAll() {
        return `This action returns all photos`;
    }

    async findOne(id: ObjectId & string, reqUser: ReqUser) {
        const [detail, focusUserCount, currentUserIsFocus, photosProfile] = await Promise.all([
            this.photosModel.findById(id).populate({ path: 'user', select: 'nickname avatar desc' }).exec(),
            this.userFocusPhotosModel.count({ photos: id }),
            this.userFocusPhotosModel.findOne({ photos: id, user: reqUser._id }, '_id'),
            this.photosProfileService.clickItem(id),
        ]);
        if (!detail.profile) {
            detail.profile = photosProfile._id;
            detail.save();
        }
        // detail 转换为普通对象
        return {
            ...detail.toObject(),
            focusUserCount,
            currentUserIsFocus: Boolean(currentUserIsFocus),
            totalDown: photosProfile.totalDown,
        };
    }

    update(id: number, updatePhotoDto: UpdatePhotoDto) {
        return `This action updates a #${id} photo`;
    }

    remove(id: number) {
        return `This action removes a #${id} photo`;
    }
}
